package net.trade.trade.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import net.core.base.dao.CommonDAO;
import net.core.common.DateFormater;
import net.core.common.StrUtils;
import net.core.common.SysConfigUtil;
import net.core.service.cache.CacheManager;
import net.core.service.cache.CacheService;
import net.core.service.encrype.CalcCRC;
import net.system.base.module.Column;
import net.system.base.module.Table;
import net.system.sys.service.ICommService;
import net.trade.base.bean.MiyinMarket;
import net.trade.base.bean.TBusilog;
import net.trade.base.bean.TTradelog;
import net.trade.common.CacheConst;
import net.trade.common.Constants;
import net.trade.service.db.CommonDB;
import net.trade.service.trade.MarketJob;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TradeServiceImpl implements ITradeService {
	@Autowired
	private CacheManager cacheManager;
	
	@Autowired
	private CommonDAO commonDAO;

	@Autowired
	private ICommService commService;

	@Autowired
	private CommonDB commonDB;
	@Autowired
	private MarketJob job;

	@Override
	public MiyinMarket getMarket() {
		CacheService cacheService = cacheManager.getCacheService();
		MiyinMarket result;
		if (cacheService.checkKey(CacheConst.CACHE_MARKET,
				Constants.MARKET_PRODUCT)) {

		} else {
			job.getMarket();

		}
		result = (MiyinMarket) cacheService.get(CacheConst.CACHE_MARKET,
				Constants.MARKET_PRODUCT);
		return result;
	}

	@Override
	public void tradeMY(HashMap map) {
		// TODO 交易操作 分为买和卖
		String type = StrUtils.getNotNullStrValue(map.get("blType"));
		if ("buy".equals(type)) {
			// 买操作
			buyMY(map);
		} else if ("sale".equals(type)) {
			// 卖操作
			saleMY(map);
		}
	}

	/**
	 * 买入操作
	 * 
	 * @param map
	 */
	private void buyMY(HashMap map) {
		// TODO Auto-generated method stub
		// TODO 判断用户的金额是否够买
		String userId = StrUtils.getNotNullStrValue(map.get("userRecId"));
		boolean bool = isOverflow(map);
		if (bool) {
			// 购买

			// 保证金，手续费
			int buyNum = StrUtils.getNotNullIntValue(StrUtils
					.getNotNullStrValue((map.get("blNum"))));
			String sTradeMoney = SysConfigUtil.getConfigValue("TRADE_MONEY",
					"TRADECFG");
			// 计算保证金 购买数量*单笔金额
			BigDecimal dbcd = new BigDecimal(buyNum
					* Integer.valueOf(sTradeMoney));
			// 计算手续费 保证金*扣除手续费比例
			String sTradeHcpre = SysConfigUtil.getConfigValue("TRADE_HCPRE",
					"TRADECFG");
			BigDecimal dbhc = dbcd.multiply(new BigDecimal(sTradeHcpre))
					.divide(new BigDecimal(100));
			// 流水号 用户crc+时间流水
			String crc = CalcCRC.getInstance().calu_CRC(userId);
			String time = DateFormater.transToNormalString(null);
			String flow = crc + time;
			// TODO 改进自动保存的玩意。可根据表名来自动生成

			// set folwno value
			map.put("blFlowno", flow);
			// 冻结保证金
			map.put("blCd", dbcd);
			map.put("blBuyhc", dbhc);
			map.put("blBuydate", time);
			map.put("suId", userId);
			map.put("blStatus", "normal");
			Table tTable = initTradeLog();
			commonDB.insertData(map, tTable);

			// TODO 更新账户信息
			BigDecimal actMoney = getActiveMoney(userId);
			BigDecimal actNowMoney = actMoney.subtract(dbcd).subtract(dbhc);
			// map.put("taActivemoney", actNowMoney);
			// map.put("taCashdeposit", dbcd);
			String sqlUpd = "update t_tradeaccount set ta_activemoney="
					+ actNowMoney.doubleValue()
					+ ", ta_cashdeposit=ta_cashdeposit+" + dbcd
					+ " where su_id='" + userId + "'";
			System.out.println(sqlUpd);
			commonDAO.updateSql(sqlUpd);
		}
	}

	/**
	 * 卖出操作
	 * 
	 * @param map
	 */
	public void saleMY(HashMap map) {
		// 卖出
		// 获取买入单号的交易信息
		String userId = StrUtils.getNotNullStrValue(map.get("userRecId"));// 用户ID
		String id = StrUtils.getNotNullStrValue((map.get("busiid")));// 交易流水ID
		TTradelog buyLog = getBuyBusi(id);// 初始化交易对象内容

		int tradeNum = buyLog.getBlNum();// 交易数量
		BigDecimal dbcd = buyLog.getBlCd();// 保证金
		int buyPoint = buyLog.getBlBuypoint();// 购买点位

		// 计算手续费 保证金*扣除手续费比例
		String sTradeHcpre = SysConfigUtil.getConfigValue("TRADE_HCPRE",
				"TRADECFG");
		BigDecimal dbhc = dbcd.multiply(new BigDecimal(sTradeHcpre)).divide(
				new BigDecimal(100));
		// 流水号 用户crc+时间流水
		String time = DateFormater.getNowTime();

		int salePoint = StrUtils.getNotNullIntValue(StrUtils
				.getNotNullStrValue((map.get("blPoint"))));// 卖出点位
		// 计算交易的盈利情况,加上买涨买跌的情况
		int pl = (salePoint - buyPoint) * tradeNum;
		if ("down".equals(buyLog.getBlDirect())) {
			// 买跌 反方向计算
			pl = -pl;
		}

		// 更新购买信息
		String sqlUpdBusi = "update t_tradelog set bl_saledate='" + time
				+ "', bl_salepoint=" + salePoint + ", bl_salehc=" + dbhc
				+ ", bl_pl=" + pl + ", bl_status='finish'" + ", rec_updatetime='"+time+"'"+ ", rec_updateperson='"+userId+"'" + " where su_id='"
				+ userId + "' and rec_id='" + id + "'";
		System.out.println(sqlUpdBusi);
		commonDAO.updateSql(sqlUpdBusi);
		// TODO 更新账户信息
		BigDecimal actMoney = getActiveMoney(userId);
		// 计算当前账户的剩余的可用余额 当前活动金额+保证金-手续费+当前盈利情况
		BigDecimal actNowMoney = actMoney.add(dbcd).subtract(dbhc).add(
				new BigDecimal(pl));
		// map.put("taActivemoney", actNowMoney);
		// map.put("taCashdeposit", dbcdsur);
		String sqlUpd = "update t_tradeaccount set ta_activemoney="
				+ actNowMoney.doubleValue()
				+ ", ta_cashdeposit=ta_cashdeposit-" + dbcd + " where su_id='"
				+ userId + "'";
		System.out.println(sqlUpd);
		commonDAO.updateSql(sqlUpd);
	}

	private TTradelog getBuyBusi(String id) {
		String sql = "SELECT t.su_id,t.bl_flowno,t.bl_buydate,t.bl_direct,t.bl_buypoint,"
				+ " t.bl_num,t.bl_cd,t.bl_buyhc,t.bl_saledate,t.bl_salepoint,t.bl_salehc,t.REC_TIME,t.REC_ID FROM t_tradelog t"
				+ " where t.rec_id='" + id + "'";
		System.out.println(sql);
		List<HashMap> list = commonDAO.getDataList(sql);
		TTradelog buyBusi = new TTradelog();
		if (null != list && list.size() > 0) {
			HashMap map = list.get(0);
			buyBusi.setSuId(StrUtils.getNotNullStrValue(map.get("su_id")));
			buyBusi.setBlFlowno(StrUtils.getNotNullStrValue(map
					.get("bl_flowno")));
			buyBusi.setBlCd(new BigDecimal(StrUtils.getNotNullStrValue(map
					.get("bl_cd"))));
			buyBusi.setBlBuydate((Date) map.get("bl_buydate"));
			buyBusi.setBlDirect(StrUtils.getNotNullStrValue(map
					.get("bl_direct")));
			buyBusi.setBlBuyhc(new BigDecimal(StrUtils.getNotNullStrValue(map
					.get("bl_buyhc"))));
			buyBusi.setBlNum(Integer.valueOf(StrUtils.getNotNullStrValue(map
					.get("bl_num"))));
			buyBusi.setBlBuypoint(Integer.valueOf(StrUtils
					.getNotNullStrValue(map.get("bl_buypoint"))));
			// String saleDate=
			// StrUtils.getNotNullStrValue(map.get("bl_saledate"));
			// System.out.println(saleDate);
			// buyBusi.setBlSaledate((Date) map.get("bl_saledate"));
			// buyBusi.setBlSalepoint(Integer.valueOf(StrUtils.getNotNullStrValue(map.get("bl_salepoint"))));
			// buyBusi.setBlSalehc(new
			// BigDecimal(StrUtils.getNotNullStrValue(map.get("bl_salehc"))));
		}
		return buyBusi;
	}

	/**
	 * 判断购买数量是否操作最大值
	 * 
	 * @param map
	 * @return
	 */
	public boolean isOverflow(HashMap map) {
		// 获取用户当前的活动金额
		String userid = StrUtils.getNotNullStrValue(map.get("userRecId"));
		BigDecimal actMoney = getActiveMoney(userid);
		String sTradeMoney = SysConfigUtil.getConfigValue("TRADE_MONEY",
				"TRADECFG");
		String sTradeRate = SysConfigUtil.getConfigValue("TRADE_RATE",
				"TRADECFG");
		String sTradeMaxnum = SysConfigUtil.getConfigValue("TRADE_MAXNUM",
				"TRADECFG");
		System.out.print("用户可用活动金额：" + actMoney + ", 单笔交易金额：" + sTradeMoney
				+ ", 购买资金比例：" + sTradeRate + ", 系统限定最大笔数：" + sTradeMaxnum);
		int buyNum = StrUtils.getNotNullIntValue(StrUtils
				.getNotNullStrValue((map.get("blNum"))));
		System.out.print(", 用户购买手数：" + buyNum);
		// 计算用户可买的最大数量
		int num = actMoney.multiply(new BigDecimal(sTradeRate)).divide(
				new BigDecimal(sTradeMoney)).divide(new BigDecimal(100))
				.intValue();
		System.out.println(", 可买手数：" + num);

		// 如果购买数量大于系统设定最大值，返回失败
		if (buyNum > Integer.valueOf(sTradeMaxnum)) {
			return false;
		}
		// 如果购买数量大于可买手数 ，返回失败
		if (buyNum > num) {
			return false;
		} else {
			return true;
		}
	}

	private BigDecimal getActiveMoney(String user) {
		String sql = "SELECT t.ta_activemoney from t_tradeaccount t WHERE t.SU_ID='"
				+ user + "'";
		List<HashMap> list = commonDAO.getDataList(sql);
		if (list.size() > 0) {
			HashMap map = list.get(0);
			BigDecimal bd = new BigDecimal(StrUtils.getNotNullStrValue(map
					.get("ta_activemoney")));
			return bd;
		}
		return null;
	}

	public Table initTrade() {
		Table trade = new Table("TBusilog", "t_busilog", "trade info",
				new ArrayList<Column>());
		trade.addColumn(new Column("blFlowno", "bl_flowno", "32", "varchar",
				false, ""));
		trade
				.addColumn(new Column("suId", "SU_ID", "20", "varchar", false,
						""));
		trade.addColumn(new Column("blDate", "bl_date", "", "TIMESTAMP", false,
				""));
		trade
				.addColumn(new Column("blType", "bl_type", "1", "char", false,
						""));
		trade.addColumn(new Column("blDirect", "bl_direct", "1", "char", false,
				""));
		trade
				.addColumn(new Column("blPoint", "bl_point", "", "int", false,
						""));
		trade.addColumn(new Column("blNum", "bl_num", "", "int", false, ""));
		trade.addColumn(new Column("blCd", "bl_cd", "", "Decimal", false, ""));
		trade.addColumn(new Column("blHc", "bl_hc", "", "Decimal", false, ""));
		trade.addColumn(new Column("blStatus", "bl_status", "10", "varchar",
				false, ""));

		trade
				.addColumn(new Column("recId", "REC_ID", "20", "varchar", true,
						""));
		trade
				.addColumn(new Column("enabled", "ENABLED", "1", "char", true,
						"1"));
		trade.addColumn(new Column("recStatus", "REC_STATUS", "1", "char",
				true, "1"));
		trade.addColumn(new Column("recPerson", "REC_PERSON", "20", "varchar",
				true, ""));
		trade.addColumn(new Column("recTime", "REC_TIME", "", "TIMESTAMP",
				true, ""));
		trade.addColumn(new Column("recUpdateperson", "REC_UPDATEPERSON", "20",
				"varchar", true, ""));
		trade.addColumn(new Column("recUpdatetime", "REC_UPDATETIME", "",
				"TIMESTAMP", true, ""));
		// String alias, String name, String length, String type, boolean++6
		// isSys,String defValue
		return trade;
	}

	public Table initTradeLog() {
		Table trade = new Table("TTradelog", "t_tradelog", "trade info",
				new ArrayList<Column>());
		trade.addColumn(new Column("blFlowno", "bl_flowno", "32", "varchar",
				false, ""));
		trade
				.addColumn(new Column("suId", "SU_ID", "20", "varchar", false,
						""));
		trade.addColumn(new Column("blDirect", "bl_direct", "1", "char", false,
				""));
		trade.addColumn(new Column("blNum", "bl_num", "", "int", false, ""));
		trade.addColumn(new Column("blCd", "bl_cd", "", "Decimal", false, ""));

		trade.addColumn(new Column("blBuydate", "bl_buydate", "", "TIMESTAMP",
				false, ""));
		trade.addColumn(new Column("blBuypoint", "bl_buypoint", "", "int",
				false, ""));
		trade.addColumn(new Column("blBuyhc", "bl_buyhc", "", "Decimal", false,
				""));

		trade.addColumn(new Column("blSaledate", "bl_saledate", "",
				"TIMESTAMP", false, ""));
		trade.addColumn(new Column("blSalepoint", "bl_salepoint", "", "int",
				false, ""));
		trade.addColumn(new Column("blSalehc", "bl_salehc", "", "Decimal",
				false, ""));

		trade.addColumn(new Column("blPl", "bl_pl", "", "Decimal", false, ""));
		trade.addColumn(new Column("blStatus", "bl_status", "10", "varchar",
				false, ""));

		trade
				.addColumn(new Column("recId", "REC_ID", "20", "varchar", true,
						""));
		trade
				.addColumn(new Column("enabled", "ENABLED", "1", "char", true,
						"1"));
		trade.addColumn(new Column("recStatus", "REC_STATUS", "1", "char",
				true, "1"));
		trade.addColumn(new Column("recPerson", "REC_PERSON", "20", "varchar",
				true, ""));
		trade.addColumn(new Column("recTime", "REC_TIME", "", "TIMESTAMP",
				true, ""));
		trade.addColumn(new Column("recUpdateperson", "REC_UPDATEPERSON", "20",
				"varchar", true, ""));
		trade.addColumn(new Column("recUpdatetime", "REC_UPDATETIME", "",
				"TIMESTAMP", true, ""));
		// String alias, String name, String length, String type, boolean++6
		// isSys,String defValue
		return trade;
	}

	public Table initAccount() {
		Table trade = new Table("TTradeaccount", "t_tradeaccount",
				"trade info", new ArrayList<Column>());
		trade.addColumn(new Column("taActivemoney", "ta_activemoney", "32",
				"varchar", false, ""));
		trade
				.addColumn(new Column("suId", "SU_ID", "20", "varchar", false,
						""));
		trade.addColumn(new Column("taCashdeposit", "ta_cashdeposit", "",
				"TIMESTAMP", false, ""));
		trade.addColumn(new Column("taPal", "ta_pal", "1", "char", false, ""));

		trade
				.addColumn(new Column("recId", "REC_ID", "20", "varchar", true,
						""));
		trade
				.addColumn(new Column("enabled", "ENABLED", "1", "char", true,
						"1"));
		trade.addColumn(new Column("recStatus", "REC_STATUS", "1", "char",
				true, "1"));
		trade.addColumn(new Column("recPerson", "REC_PERSON", "20", "varchar",
				true, ""));
		trade.addColumn(new Column("recTime", "REC_TIME", "", "TIMESTAMP",
				true, ""));
		trade.addColumn(new Column("recUpdateperson", "REC_UPDATEPERSON", "20",
				"varchar", true, ""));
		trade.addColumn(new Column("recUpdatetime", "REC_UPDATETIME", "",
				"TIMESTAMP", true, ""));
		// String alias, String name, String length, String type, boolean++6
		// isSys,String defValue
		return trade;
	}

	@Override
	public List<HashMap> getUserOrder(String userId) {
		String sql = "select t.su_id,t.bl_flowno,t.bl_direct,case when t.bl_direct='buy' then '买涨' else '买跌' end direct, t.bl_buypoint,"
				+ " t.bl_num,t.bl_cd,t.bl_buyhc,t.rec_id FROM t_tradelog t"
				+ " where t.bl_status='normal' and t.SU_ID='" + userId + "'";
		List<HashMap> list = commonDAO.getDataList(sql);

		return list;
	}

	@Override
	public List<HashMap> getUserAccount(String userId) {
		String sql = "SELECT t.ta_activemoney,t.ta_cashdeposit,t.ta_pal,t.SU_ID FROM t_tradeaccount t"
				+ " where t.SU_ID='" + userId + "'";
		List<HashMap> list = commonDAO.getDataList(sql);

		return list;
	}

	@Override
	public String getMiyin() {
		CacheService cacheService = cacheManager.getCacheService();
		String result;
		if (cacheService.checkKey(CacheConst.CACHE_MIYIN,
				Constants.MIYIN_PRODUCT)) {

		} else {
			job.getMarket();

		}
		result = (String) cacheService.get(CacheConst.CACHE_MIYIN,
				Constants.MIYIN_PRODUCT);
		return result;
	}

	

}
